/*
 * This file is part of Cadmium.
 * Copyright (C) 2007-2010 Xavier Clerc.
 *
 * Cadmium is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Cadmium is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package fr.x9c.cadmium.kernel;

import java.io.PrintStream;
import java.util.Map;

/**
 * This interface defines the bare minimum contract of code runners under the
 * Cadmium runtime, whether they are running compiled or interpreted code.
 *
 * @author <a href="mailto:cadmium@x9c.fr">Xavier Clerc</a>
 * @version 1.2
 * @since 1.0
 */
public interface CodeRunner extends Runnable {

    /** Index of <i>TERMINATED</i> field in thread status. */
    int TERMINATED = 2;

    /**
     * Returns the underlying context.
     * @return the underlying context
     */
    Context getContext();

    /**
     * Tests whether the runner is native (that is Java bytecode)
     * or interpreted (that is OCaml bytecode).
     * @return <tt>true</tt> if the runner is Java bytecode,
     *         <tt>false</tt> otherwise
     */
    boolean isNative();

    /**
     * Sets the scripting bindings for this code runner.
     * @param b scripting bindings for this code runner
     */
    void setBindings(Map<String, Value> b);

    /**
     * Returns the scripting bindings for this code runner.
     * @return the scripting bindings for this code runner
     */
    Map<String, Value> getBindings();

    /**
     * Returns the thread status.
     * @return the thread status
     */
    Value getThreadStatus();

    /**
     * Changes the thread status.
     * @param ts new thread status - should not be <tt>null</tt>
     */
    void setThreadStatus(final Value ts);

    /**
     * Constructs a new code runner from the current runner.
     * @param status thread status (can be <tt>null</tt>)
     * @return newly created code runner
     */
    CodeRunner createNewThread(final Value status);

    /**
     * Changes both closure to be executed and arguments for it.
     * @param closure closure to be executed
     * @param args parameters for closure to be executed
     */
    void setup(final Value closure, final Value... args);

    /**
     * Executes a closure with given parameters. <br/>
     * (internally used by callbacks/proxies)
     * @param closure closure to be executed - should not be <tt>null</tt>
     * @param params parameters to closure - should not be <tt>null</tt> <br/>
     *               it is the responsibility of the programmer to supply the
     *               correct number and types of parameters
     * @return the value returned by closure application to the parameters
     * @throws Fail.Exception if thrown by closure execution
     * @throws Fatal.Exception if thrown by closure execution
     * @throws CadmiumException if an internal error occurs
     */
    Value callback(final Value closure, final Value... params)
        throws Fail.Exception, Fatal.Exception, FalseExit, CadmiumException;

    /**
     * Executes a closure with given parameters. <br/>
     * (internally used by callbacks/proxies)
     * @param function function to be executed - should not be <tt>null</tt>
     * @param params parameters to closure - should not be <tt>null</tt> <br/>
     *               it is the responsibility of the programmer to supply the
     *               correct number and types of parameters
     * @return the value returned by closure application to the parameters
     * @throws Fail.Exception if thrown by closure execution
     * @throws Fatal.Exception if thrown by closure execution
     * @throws CadmiumException if an internal error occurs
     */
    Value callback(final String function, final Value... params)
        throws Fail.Exception, Fatal.Exception, FalseExit, CadmiumException;

    /**
     * Prints all backtrace elements onto the passed stream.
     * @param out error stream - should not be <tt>null</tt>
     */
    void printExceptionBacktrace(final PrintStream out);

    /**
     * Returns all backtrace elements.
     * @return all backtrace elements
     */
    Value getExceptionBacktrace();

    /**
     * Clears the backtrace information.
     */
    void clearBacktraceInfo();

} // end interface 'CodeRunner'
